package gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import logic.OpenGame;
import logic.SaveGame;
import messages.DisconnectFromServer;
import messages.GameEventDispatcher;
import messages.GameEventListener;
import messages.GameMessage;
import messages.NewGame;
import messages.QuitGame;
import messages.ResetMatch;
import messages.StartGameServer;
import messages.StopGameServer;

public class GameMenu extends JMenuBar implements ActionListener, GameEventDispatcher {
	
	/**
	 * 
	 */
	private class GameMenuUtils{
		public final static String open = "openNewGame";
		public final static String newGame = "newGame";
		public final static String reset = "resetGame";
		public final static String save = "saveGame";
		public final static String connect = "connectGame";
		public final static String disconnect = "disconnectGame";
		public final static String quit = "quit";
		
		public final static String startServer = "startServer";
		public final static String stopServer = "stopServer";
		public final static String preferences = "preferences";
	}
	
	private static final long serialVersionUID = 2472001129157982087L;
	private ArrayList<GameEventListener> listeners;

	private JMenuItem openNewGame = new JMenuItem("Open new game");
	private JMenuItem newGame = new JMenuItem("New game");
	private JMenuItem resetGame = new JMenuItem("Reset game");
	private JMenuItem saveGame = new JMenuItem("Save game");
	private JMenuItem connectGame = new JMenuItem("Connect");
	private JMenuItem disconnectGame = new JMenuItem("Disconnect");
	
	private JMenuItem startServer = new JMenuItem("Start server");
	private JMenuItem stopServer = new JMenuItem("Stop server");
	private JMenuItem preferencesSetting = new JMenuItem("Preferences");
	
	private JMenuItem rulesHelp = new JMenuItem("Game Rules");
	private JMenuItem gameHelp = new JMenuItem("FreeKhet help");
	private JMenuItem aboutHelp = new JMenuItem("About");
	
	
	public GameMenu(GameEventListener listener){
		listeners = new ArrayList<GameEventListener>();
		listeners.add(listener);
		JMenu settingMenu = new JMenu("Settings");
		JMenu gameMenu = new JMenu("Game");
		JMenu helpMenu = new JMenu("Help");
		this.add(gameMenu);
		this.add(settingMenu);
		this.add(helpMenu);
		

		openNewGame.setName(GameMenuUtils.open);
		newGame.setName(GameMenuUtils.newGame);
		resetGame.setName(GameMenuUtils.reset);
		saveGame.setName(GameMenuUtils.save);
		connectGame.setName(GameMenuUtils.connect);
		disconnectGame.setName(GameMenuUtils.disconnect);
		resetGame.addActionListener(this);
		newGame.addActionListener(this);
		connectGame.addActionListener(this);
		saveGame.addActionListener(this);
		openNewGame.addActionListener(this);
		disconnectGame.setEnabled(false);
		disconnectGame.addActionListener(this);
		JMenuItem quitGame = new JMenuItem("Quit");
		quitGame.setName(GameMenuUtils.quit);
		quitGame.addActionListener(this);
		gameMenu.add(openNewGame);
		gameMenu.add(newGame);
		gameMenu.add(resetGame);
		gameMenu.add(saveGame);
		gameMenu.addSeparator();
		gameMenu.add(connectGame);
		gameMenu.add(disconnectGame);
		gameMenu.addSeparator();
		gameMenu.add(quitGame);
		
		startServer.setName(GameMenuUtils.startServer);
		stopServer.setName(GameMenuUtils.stopServer);
		stopServer.setEnabled(false);
		preferencesSetting.setName(GameMenuUtils.preferences);
		startServer.addActionListener(this);
		stopServer.addActionListener(this);
		settingMenu.add(startServer);
		settingMenu.add(stopServer);
		settingMenu.addSeparator();
		settingMenu.add(preferencesSetting);
		
		helpMenu.add(rulesHelp);
		helpMenu.add(gameHelp);
		helpMenu.addSeparator();
		helpMenu.add(aboutHelp);
		
	}
	
	public void clientConnected(){
		openNewGame.setEnabled(false);
		resetGame.setEnabled(false);
		newGame.setEnabled(false);
		
		connectGame.setEnabled(false);
		startServer.setEnabled(false);
		stopServer.setEnabled(false);
		
		disconnectGame.setEnabled(true);
	}
	
	public void clientDisconnected(){
		openNewGame.setEnabled(true);
		resetGame.setEnabled(true);
		newGame.setEnabled(true);
		
		connectGame.setEnabled(true);
		startServer.setEnabled(true);
		stopServer.setEnabled(true);
		
		disconnectGame.setEnabled(false);		
	}
	
	public void startServer(){
		startServer.setEnabled(false);
		stopServer.setEnabled(true);
		
		openNewGame.setEnabled(false);
		resetGame.setEnabled(false);
		newGame.setEnabled(false);
		
		connectGame.setEnabled(false);
		startServer.setEnabled(false);
	}
	
	public void stopServer(){
		openNewGame.setEnabled(true);
		resetGame.setEnabled(true);
		newGame.setEnabled(true);
		
		connectGame.setEnabled(true);
		startServer.setEnabled(true);
		stopServer.setEnabled(false);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() instanceof JMenuItem){
			JMenuItem menu = (JMenuItem) e.getSource();
			String action = menu.getName();
			if(action.equals(GameMenuUtils.reset)){
				/*
				 * Reset current game actions
				 */
				sendEvent(new ResetMatch());
			}
			if(action.equals(GameMenuUtils.newGame)){
				/*
				 * New game, also reset scores
				 */
				sendEvent(new NewGame());
			}
			if(action.equals(GameMenuUtils.connect)){
				/*
				 * Open a dialog of connection.
				 */
				ConnectionMenu cMenu = new ConnectionMenu();
				for(GameEventListener listener:listeners)
					cMenu.registerGameListener(listener);
				cMenu.setVisible(true);
			}
			if(action.equals(GameMenuUtils.quit)){
				sendEvent(new QuitGame());
			}
			if(action.equals(GameMenuUtils.save)){
				/* TODO
				 * Open a menu Save As
				 */
				sendEvent(new SaveGame("freekhet"+System.currentTimeMillis()+".xml"));
			}
			if(action.equals(GameMenuUtils.open)){
				JFileChooser open = new JFileChooser();
				int rt = open.showOpenDialog(this);
				if(rt==JFileChooser.APPROVE_OPTION){
					OpenGame message = new OpenGame();
					String file = open.getSelectedFile().getName();
					message.setMessage(file);
					sendEvent(message);
				}
			}
			if(action.equals(GameMenuUtils.startServer)){
				sendEvent(new StartGameServer());
			}
			if(action.equals(GameMenuUtils.stopServer)){
				sendEvent(new StopGameServer());
			}
			if(action.equals(GameMenuUtils.disconnect)){
				sendEvent(new DisconnectFromServer());
			}
		}
		
	}

	@Override
	public void sendEvent(GameMessage event) {
		for(GameEventListener listener:listeners){
			listener.gameEvent(event);
		}
	}

	@Override
	public void registerGameListener(GameEventListener listener) {
		listeners.add(listener);
	}
	

}
